<!--
 * @Author: WangShuai 1830773767@qq.com
 * @Date: 2024-01-14 20:42:16
 * @LastEditors: WangShuai 1830773767@qq.com
 * @LastEditTime: 2025-06-18 19:20:18
 * @FilePath: \vue3_admin_template\project\src\views\acl\user\index.vue
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
-->
<template>
  <div>
    <el-card>
      <el-form ref="form" :inline="true" label-width="80px" class="form">
        <el-form-item label="用户名">
          <el-input placeholder="请输入搜索用户名" v-model="keyWord"></el-input>
        </el-form-item>
        <el-form-item label="">
          <el-button
            type="primary"
            :disabled="keyWord == '' ? true : false"
            @click="serach"
          >
            搜索
          </el-button>
          <el-button :plain="true" @click="reSet">重置</el-button>
        </el-form-item>
      </el-form>
    </el-card>
    <el-card style="margin: 10px 0">
      <el-button type="primary" @click="addUser" v-has="`btn.User.add`">
        添加用户
      </el-button>
      <el-button
        type="primary"
        @click="removeALL"
        :disabled="selectArr.length > 0 ? false : true"
        v-has="`btn.User.remove`"
      >
        批量删除
      </el-button>
      <el-table
        :data="userArr"
        style="width: 100%; margin: 10px 0"
        border
        @selection-change="handleSelectionChange"
      >
        <el-table-column type="selection" width="50px"></el-table-column>
        <el-table-column
          type="index"
          label="序号"
          width="80px"
          align="center"
        ></el-table-column>
        <el-table-column align="center" prop="id" label="ID"></el-table-column>
        <el-table-column
          align="center"
          prop="username"
          label="用户名字"
        ></el-table-column>
        <el-table-column
          align="center"
          prop="name"
          label="用户昵称"
        ></el-table-column>
        <el-table-column
          align="center"
          prop="roleName"
          label="用户角色"
          show-overflow-tooltip
        ></el-table-column>
        <el-table-column
          align="center"
          prop="createTime"
          show-overflow-tooltip
          label="创建时间"
        ></el-table-column>
        <el-table-column
          align="center"
          prop="updateTime"
          show-overflow-tooltip
          label="更新时间"
        ></el-table-column>
        <el-table-column align="center" label="操作" width="280px">
          <template #="{ row }">
            <el-button
              type="primary"
              size="small"
              title="分配角色"
              icon="user"
              @click="setRole(row)"
              v-has="`btn.User.assgin`"
            >
              分配角色
            </el-button>
            <el-button
              type="primary"
              size="small"
              title="编辑"
              icon="Edit"
              @click="updateUser(row)"
              v-has="`btn.User.update`"
            >
              编辑
            </el-button>
            <el-popconfirm
              class="box-item"
              :title="`确定要删除${row.name}么?`"
              placement="top-start"
              @confirm="removeUser(row)"
              @cancel="removeCancel"
              width="200px"
            >
              <template #reference>
                <el-button
                  type="primary"
                  size="small"
                  title="删除"
                  icon="Delete"
                  v-has="`btn.User.remove`"
                >
                  删除
                </el-button>
              </template>
            </el-popconfirm>
          </template>
        </el-table-column>
      </el-table>
      <el-pagination
        style="margin: 10px 0"
        v-model:current-page="pageInfo.pageNo"
        v-model:page-size="pageInfo.limit"
        :page-sizes="[3, 5, 7, 10]"
        size="small"
        :background="true"
        layout=" prev, pager, next, jumper,->,sizes,total,"
        :total="pageInfo.total"
        @size-change="handleSizeChange"
        @current-change="getUserInfo"
      />
    </el-card>
    <!-- 抽屉组件 用于添加新的用户和更新用户信息 -->
    <el-drawer v-model="drawer" direction="rtl">
      <!-- 头部标题 -->
      <template #header>
        <h4>{{ userParams.id ? '编辑' : '添加' }}用户</h4>
      </template>
      <template #default>
        <el-form
          ref="formRef"
          label-width="80px"
          :model="userParams"
          :rules="rules"
        >
          <el-form-item label="用户姓名" style="margin: 20px 0" prop="username">
            <el-input
              v-model="userParams.username"
              placeholder="请您输入姓名"
            ></el-input>
          </el-form-item>
          <el-form-item label="用户昵称" style="margin: 20px 0" prop="name">
            <el-input
              v-model="userParams.name"
              placeholder="请您输入昵称"
            ></el-input>
          </el-form-item>
          <el-form-item
            label="用户密码"
            style="margin: 20px 0"
            prop="password"
            v-if="!userParams.id"
          >
            <el-input
              v-model="userParams.password"
              placeholder="请您输入密码"
            ></el-input>
          </el-form-item>
        </el-form>
      </template>
      <template #footer>
        <div style="flex: auto">
          <el-button @click="cancelClick">取消</el-button>
          <el-button type="primary" @click="save">确定</el-button>
        </div>
      </template>
    </el-drawer>
    <!-- 用于显示 分配用户角色的显示和隐藏 -->
    <el-drawer v-model="drawer2" direction="rtl">
      <!-- 头部标题 -->
      <template #header>
        <h4>分配角色(职位)</h4>
      </template>
      <template #default>
        <el-form
          ref="formRef"
          label-width="80px"
          :model="userParams"
          :rules="rules"
        >
          <el-form-item label="用户姓名" style="margin: 20px 0">
            <el-input
              v-model="userParams.username"
              placeholder="请您输入姓名"
              :disabled="true"
            ></el-input>
          </el-form-item>
          <el-form-item label="职位列表" style="margin: 20px 0">
            <el-checkbox
              v-model="checkAll"
              :indeterminate="isIndeterminate"
              @change="handleCheckAllChange"
              style="width: 100%"
            >
              全选
            </el-checkbox>
            <!-- 显示职位的复选框 -->
            <el-checkbox-group
              v-model="userRoleList"
              @change="handleCheckedRolesChange"
            >
              <el-checkbox
                v-for="item in allRoleList"
                :key="item.id"
                :label="item"
                :value="item.roleName"
              >
                {{ item.roleName }}
              </el-checkbox>
            </el-checkbox-group>
          </el-form-item>
        </el-form>
      </template>
      <template #footer>
        <div style="flex: auto">
          <el-button @click="cancelClick">取消</el-button>
          <el-button type="primary" @click="confirm">确定</el-button>
        </div>
      </template>
    </el-drawer>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, onMounted, nextTick } from 'vue'
import {
  reqAllUserInfo,
  reqAddOrUpdateUser,
  reqAllRole,
  reqDoAssignRole,
  reqRemoveUser,
  reqRemoveAll,
} from '@/api/acl/user'
import type {
  UserResponseData,
  Records,
  User,
  AllRoleResponseData,
  AllRole,
  SetRoleData,
} from '@/api/acl/user/type'
import useUserStore from '@/store/modules/user'
import { ElMessage } from 'element-plus'
import type { CheckboxValueType } from 'element-plus'
import useLayoutSettingStore from '@/store/modules/setting'
//获取模板setting仓库
let settingStore = useLayoutSettingStore()
//全选复选框收集数据:全选或者取消全选
const checkAll = ref<boolean>(false)
//非全选时设置的样式
const isIndeterminate = ref<boolean>(true)
const allRoleList = ref<AllRole>([])
//选择分配角色的数组
const userRoleList = ref<AllRole>([])
//获取当前登录的用户信息
let currentUserObj = useUserStore()
let pageInfo = reactive({
  pageNo: 1,
  limit: 5,
  total: 0,
})
//获取表单实例
let formRef = ref()
//控制抽屉显示和隐藏
let drawer = ref<boolean>(false)
//分配角色 抽屉
let drawer2 = ref<boolean>(false)
//保存全部已有用户信息
let userArr = ref<Records>([])
//仅用来保存修改之前的当前登录的用户
let copyUser = reactive<User>({
  username: '',
  name: '',
  password: '',
})
//用户输入关键字
let keyWord = ref('')
onMounted(() => {
  getUserInfo()
})
let userParams = reactive<User>({
  username: '',
  name: '',
  password: '',
})
//@ts-ignore
const validatorUsername = (rule: any, value: any, callback: any) => {
  //用户名字|昵称长度至少5位
  if (value.trim().length >= 5) {
    callback()
  } else {
    callback(new Error('用户名字长度至少5位'))
  }
} //@ts-ignore
const validatorName = (rule: any, value: any, callback: any) => {
  //用户名字|昵称长度至少5位
  if (value.trim().length >= 5) {
    callback()
  } else {
    callback(new Error('用户昵称长度至少5位'))
  }
}
//@ts-ignore
const validatorPassword = (rule: any, value: any, callback: any) => {
  //用户密码长度至少6位
  if (value.trim().length >= 5) {
    callback()
  } else {
    callback(new Error('用户密码长度至少6位'))
  }
}
//表单自定义校验规则
//注意?? trigger:"change" 当点击添加用户时 清空上一次用户信息Object.assign(userParams, {})会触发表单验证方法
const rules = {
  username: [{ required: true, trigger: 'blur', validator: validatorUsername }],
  name: [{ required: true, trigger: 'blur', validator: validatorName }],
  password: [{ required: true, trigger: 'blur', validator: validatorPassword }],
}
//获取全部已有用户信息
const getUserInfo = async (pager = 1) => {
  pageInfo.pageNo = pager
  let result: UserResponseData = await reqAllUserInfo(
    pageInfo.pageNo,
    pageInfo.limit,
    keyWord.value,
  )
  if (result.code == 200) {
    userArr.value = result.data.records
    pageInfo.total = result.data.total
  }
}
//改变每页条数
const handleSizeChange = () => {
  //   pageInfo.limit = value
  getUserInfo()
}
//新添加用户操作
const addUser = () => {
  drawer.value = true
  Object.assign(userParams, {
    id: 0,
    username: '',
    name: '',
    password: '',
  })
  nextTick(() => {
    //清除表单上一次的错误的验证信息
    formRef.value.clearValidate('username')
    formRef.value.clearValidate('name')
    formRef.value.clearValidate('password')
  })
}
//更新已有用户按钮回调
const updateUser = (row: User) => {
  drawer.value = true
  Object.assign(userParams, row)
  nextTick(() => {
    //清除表单上一次的错误的验证信息
    formRef.value.clearValidate('username')
    formRef.value.clearValidate('name')
  })
  copyUser.username = row.username
}
//确定按钮事件回调
const save = async () => {
  //保证表单验证条件全部通过后才能发起保存请求
  //validate() 全部通过后返回成功的
  await formRef.value.validate()
  let result: any = await reqAddOrUpdateUser(userParams)
  if (result.code == 200) {
    drawer.value = false
    ElMessage({
      type: 'success',
      message: `${userParams.id ? '更新' : '添加'}用户成功!`,
    })
    getUserInfo(userParams.id ? pageInfo.pageNo : 1)
    //如果修改当前正在登录的用户账号 在进行浏览器重新加载
    if (copyUser.username == currentUserObj.username) {
      //浏览器自动刷新一次
      window.location.reload()
    }
  } else {
    drawer.value = false
    ElMessage({
      type: 'error',
      message: `${userParams.id ? '更新' : '添加'}用户失败!`,
    })
  }
}
//取消操作
const cancelClick = () => {
  drawer.value = false
}
//删除用户信息
const removeUser = async (row: User) => {
  let result = await reqRemoveUser(row.id as number)
  if (result.code == 200) {
    ElMessage({
      type: 'success',
      message: '删除用户成功!',
    })
    getUserInfo(
      userArr.value.length > 1 ? pageInfo.pageNo : pageInfo.pageNo - 1,
    )
  } else {
    ElMessage({
      type: 'error',
      message: '删除用户失败!',
    })
  }
}
//取消删除
const removeCancel = () => {
  ElMessage({
    type: 'success',
    message: '取消删除用户成功!',
  })
}

//分配角色按钮回调
const setRole = async (row: User) => {
  Object.assign(userParams, row)
  //发请求获取全部职位数据
  let result: AllRoleResponseData = await reqAllRole(userParams.id as number)
  if (result.code == 200) {
    allRoleList.value = result.data.allRolesList
    //存储当用户已有的职位
    userRoleList.value = result.data.assignRoles
    drawer2.value = true
  }
}
//全选或者取消全选事件回调
const handleCheckAllChange = (val: CheckboxValueType) => {
  //console.log(val);//全选 true 或 非全选 false
  userRoleList.value = val ? allRoleList.value : []
  //非全选样式
  isIndeterminate.value = false
}
//职位角色复选框事件回调
const handleCheckedRolesChange = (value: CheckboxValueType[]) => {
  //  已经勾选的复选框组成的数组
  const checkedCount = value.length
  checkAll.value = checkedCount === allRoleList.value.length
  //设置半选状态
  isIndeterminate.value =
    checkedCount > 0 && checkedCount < allRoleList.value.length
}
//保存分配角色确定事件回调
const confirm = async () => {
  //收集参数
  let data: SetRoleData = {
    userId: userParams.id as number,
    roleIdList: userRoleList.value.map((item) => item.id as number),
  }
  let result = await reqDoAssignRole(data)
  if (result.code == 200) {
    ElMessage({
      type: 'success',
      message: '分配职位成功!',
    })
    getUserInfo(userParams.id ? pageInfo.pageNo : 1)
    drawer2.value = false
  } else {
    ElMessage({
      type: 'error',
      message: '分配职位失败!',
    })
  }
}
//存储批量删除的ID
let selectArr = ref<User[]>([])
//批量选择用户
const handleSelectionChange = (val: any) => {
  selectArr.value = val
  console.log(selectArr)
}
//批量删除用户
const removeALL = async () => {
  //整理批量删除的参数
  let idList = selectArr.value
    .map((item) => item.id)
    .filter((id): id is number => typeof id === 'number') as number[] // 断言为 number[]
  if (idList.length > 0) {
    let result = await reqRemoveAll(idList)
    if (result.code == 200) {
      ElMessage({
        type: 'success',
        message: '删除用户成功!',
      })
      getUserInfo(
        userArr.value.length > 1 ? pageInfo.pageNo : pageInfo.pageNo - 1,
      )
    } else {
      ElMessage({
        type: 'error',
        message: '删除用户失败!',
      })
    }
  }
}
//搜索按钮事件回调
const serach = () => {
  //根据关键字获取相应的用户数据
  getUserInfo()
  keyWord.value = ''
}
//重置按钮
const reSet = () => {
  settingStore.refsh = !settingStore.refsh
}
</script>

<style lang="scss" scoped>
.form {
  display: flex;
  justify-content: space-between;
  align-items: center;
  .el-form-item {
    display: flex;
    --font-size: 14px;
    margin-bottom: 0px;
  }
}
</style>
